/*
 * Copyright (c) 2008 by 1eEurope (Switzerland) AG, Thalwil
 *
 * Customer:	1eEurope (Switzerland) AG
 * Project:		BKS
 * Created:		30.09.2008, WBL
 *
*/

using System;
using System.Web.Configuration;
using System.Web.Services.Protocols;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Microsoft.Office.Server.Search.Query;
using Microsoft.Office.Server;
using System.Xml;
using System.Text.RegularExpressions;
using System.Globalization;
using Microsoft.SharePoint;

namespace By1eEurope.BKS.Controls
{
    /// <summary>
    /// SearchProvider implementation for SharePoint Search
    /// </summary>
    public class SharePointAPISearchProvider : ISearchProvider
    {
        protected int _maxQueryLength = 50;

        public SearchResults ExecuteQuery(string queryText, int resultsPerPage, int resultsPageIndex, bool highlight, string highlightBefore, string highlightAfter, string scope)
        {
            SearchResults results = new SearchResults();
            
            try
            {
                int totalResults = 0;
                // we limit the query to 50 characters
                if (queryText.Length > _maxQueryLength)
                    queryText = queryText.Substring(0, _maxQueryLength);
                
                using (SPSite site = new SPSite(SPContext.Current.Site.Url))
                {
                    FullTextSqlQuery query = new FullTextSqlQuery(site);
                    query.ResultTypes = ResultType.RelevantResults;
                    query.Culture = CultureInfo.CurrentCulture;
                    query.SiteContext = new Uri(SPContext.Current.Site.Url);
                    query.HighlightedSentenceCount = 3;
                    query.TrimDuplicates = true;

                    string queryStatement = "";
                    queryText = queryText.Replace("'", "");
                    if (queryText.Contains("*"))
                    {
                        // do a wildcard search
                        query.KeywordInclusion = KeywordInclusion.AnyKeyword;
                        query.EnableStemming = false;
                        //queryStatement = "SELECT Path, Rank, Title, HitHighlightedSummary FROM {0}..scope() WHERE \"scope\"='{1}' AND CONTAINS ('\"{2}\"') ORDER By Rank DESC";
                        queryStatement = "SELECT Path, Rank, Title, HitHighlightedSummary FROM SCOPE() WHERE \"scope\"='{0}' AND CONTAINS ('\"{1}\"') ORDER By Rank DESC";
                    }
                    else
                    {
                        if (queryText.Contains("'"))
                        {
                            // currently we only allow searching for one 'exact term'
                            queryText = queryText.Replace("'", "");
                            if (queryText.Length > 0)
                                queryText = "\"" + queryText + "\"";
                        }
                        if (queryText.Contains("\""))
                        {
                            // search for an 'exact term'
                            query.KeywordInclusion = KeywordInclusion.AllKeywords;
                        }
                        else 
                        {
                            query.KeywordInclusion = KeywordInclusion.AnyKeyword;
                        }
                        query.EnableStemming = true;
                        //queryStatement = "SELECT Path, Rank, Title, HitHighlightedSummary FROM {0}..scope() WHERE \"scope\"='{1}' AND FREETEXT(DefaultProperties, '{2}') ORDER By Rank DESC";
                        queryStatement = "SELECT Path, Rank, Title, HitHighlightedSummary FROM SCOPE() WHERE \"scope\"='{0}' AND FREETEXT(DefaultProperties, '{1}') ORDER By Rank DESC";
                    }

                    if (queryText != string.Empty)
                    {
                        query.QueryText = string.Format(queryStatement,scope,queryText);
                        query.StartRow = (resultsPageIndex * resultsPerPage);
                        query.RowLimit = resultsPerPage;

                        // run the query and get the response
                        ResultTableCollection searchResults = query.Execute();
                        ResultTable result = searchResults[ResultType.RelevantResults];
                        
                        while (result.Read())
                        {
                            string url = "";
                            string title = "";
                            string description = "";

                            if (result[0] != null)
                                url = result[0].ToString();
                            if (result[2] != null)
                                title = result[2].ToString();
                            if (result[3] != null)
                                description = result[3].ToString();

                            // if hightlighting is enabled, replace all <c?></c?> instances (such as <c0>, <c1> etc.)
                            // with <b></b>, otherwise with an empty string
                            if (highlight)
                            {
                                description = Regex.Replace(description, @"<c\d+>", highlightBefore);
                                description = Regex.Replace(description, @"</c\d+>", highlightAfter);
                            }

                            results.WebResults.Add(new ResultItem(url, title, description));
                        }

                        results.TotalResults = result.TotalRows;
                    }
                }
            }
            catch (Exception)
            {
                results.TotalResults = 0;
            }

            return results;
        }
    }
}